package com.zx.scp.service.impl;


import com.zx.map.utils.*;
import com.zx.map.wx.WxOauthHelper;
import com.zx.platform.utils.DateUtils;
import com.zx.platform.utils.HttpParamsUtils;
import com.zx.platform.utils.PmpUtils;
import com.zx.platform.utils.TmDateUtil;
import com.zx.scp.service.IIncomeService;
import com.zx.scp.service.IncomHandleService;
import com.zx.scp.service.model.OrderPayCallBackModel;
import com.zx.scp.service.model.YintongPayNofityModel;
import com.zx.scp.service.model.YintongPayRequestModel;
import com.zx.scp.service.util.swift.MD5;
import com.zx.scp.service.util.swift.SignUtils;
import com.zx.scp.service.util.swift.XmlUtils;
import com.zx.scp.utils.PropertyUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by bibei on 2017/3/20.
 * 威富通支付
 */
@Service
public class SwiftPayIncomeServiceImpl  implements IIncomeService {
	public static Logger logger = Logger.getLogger(SwiftPayIncomeServiceImpl.class.getSimpleName());
	@Autowired
	private IncomHandleService incomHandleService;

	/**
	 * 微信 公众号支付
	 *
	 * @param request
	 * @param yintongPayRequestModel
	 * @return
	 * @throws Exception
	 */
	@Override
	public Map winxinJsPay(HttpServletRequest request, YintongPayRequestModel yintongPayRequestModel) throws Exception {
		//获取支付信息
		CloseableHttpResponse response = null;
		CloseableHttpClient client = null;
		try {
			int orderEffectiveTime = Integer.valueOf(PropertyUtil.getValue("order_effective_time"));
			Map paramMap = new HashMap<String, String>();
			paramMap.put("service", "pay.weixin.jspay");
			paramMap.put("is_raw", "0");// 是否原生态	值为1：是；值为0：否；不传默认是0
			// paramMap.put("callback_url", orderResponseDomain.getCallBackUrl());// 交易完成后跳转的URL，需给绝对路径
			paramMap.put("sub_openid", yintongPayRequestModel.getOpenId());
			paramMap.put("sub_appid", WxOauthHelper.APPID);

			//通用参数
			paramMap.put("version", "2.0");
			paramMap.put("charset", "UTF-8");
			paramMap.put("mch_id", PropertyUtil.getValue("swift_mer_id"));
			paramMap.put("out_trade_no", yintongPayRequestModel.getOrderId());
			//paramMap.put("device_info","device_info");
			paramMap.put("body", "微信付款");
			paramMap.put("total_fee", yintongPayRequestModel.getAmount());
			paramMap.put("mch_create_ip", IPMacUtils.getIpAddr(request));
			paramMap.put("notify_url", PropertyUtil.getValue("swiftpay_notify_url"));
			paramMap.put("nonce_str", TmDateUtil.nowTime(TmDateUtil.TIMESTAMP_FOMART_OTHER) + RandomStringUtils.random(4, true, true));
			if (orderEffectiveTime > 0) {
				paramMap.put("time_start", DateFormatUtils.format(new Date(), DateUtils.DATE_TIME_FMT_OTHER));
				paramMap.put("time_expire",DateFormatUtils.format(TmDateUtil.addHours(new Date(),orderEffectiveTime), DateUtils.DATE_TIME_FMT_OTHER));
			}
			String preStr = HttpParamsUtils.buildPayParams(paramMap, false, true);
			logger.debug("威富通加密前:" + preStr);
			String sign = MD5.sign(preStr, "&key=" + PropertyUtil.getValue("swift_mer_key"), "utf-8");
			paramMap.put("sign", sign);
			String requestStr = XmlUtils.parseXML(paramMap);
			logger.debug("威富通 微信公众号支付 请求参数:" + requestStr);
			HttpPost httpPost = new HttpPost(PropertyUtil.getValue("swiftpay_req_url"));
			StringEntity entityParams = new StringEntity(requestStr, "utf-8");
			httpPost.setEntity(entityParams);
			httpPost.setHeader("Content-Type", "text/xml;charset=ISO-8859-1");
			client = HttpClients.createDefault();
			response = client.execute(httpPost);
			if (response != null && response.getEntity() != null) {
				InputStream resStream = response.getEntity().getContent();
				logger.debug("威富通 微信公众号支付请求返回参数：" + resStream.toString());
				Map<String, String> resultMap = XmlUtils.toMap(resStream, "utf-8");
				if (resultMap.containsKey("sign")) {
					if (SignUtils.checkParam(resultMap, PropertyUtil.getValue("swift_mer_key"))) {
						if ("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))) {
							resultMap.put("codeUrl", PropertyUtil.getValue("swiftpay_jspay_url") + resultMap.get("token_id"));//转换支付链接url
							resultMap.put("payInfo", resultMap.get("pay_info"));
							resultMap.remove("pay_info");//移除无效的字段
							return CommonResponseUtils.successResponse(resultMap);
						}
					}
				}
				return CommonResponseUtils.failureResponse(resultMap.get("message"));
			} else {
				logger.debug("威富通 微信公众号支付 服务器异常");
				return CommonResponseUtils.failureResponse(SUConstants.SERVER_ERROR);
			}
		} catch (Exception e) {
			logger.debug("威富通 微信公众号支付 获取支付异常", e);
			return CommonResponseUtils.failureResponse(SUConstants.SERVER_ERROR);
		} finally {
			if (response != null) {
				response.close();
			}
			if (client != null) {
				client.close();
			}
		}
	}

	/**
	 * 获取支付信息
	 *
	 * @return
	 */
	@Override
	public Map startPay(HttpServletRequest request, YintongPayRequestModel yintongPayRequestModel) throws Exception {
		//获取支付信息
		CloseableHttpResponse response = null;
		CloseableHttpClient client = null;
		try {
			int orderEffectiveTime = Integer.valueOf(PropertyUtil.getValue("order_effective_time"));
			Map paramMap = new HashMap<String, String>();
			if (yintongPayRequestModel.getPayType().equals(SUConstants.paymentTypeWX)) {
				paramMap.put("service", "pay.weixin.native");
				paramMap.put("body", "微信付款");
			} else {
				paramMap.put("service", "pay.alipay.native");
				paramMap.put("body", "支付宝付款");
			}
			
			paramMap.put("version", "2.0");
			paramMap.put("charset", "UTF-8");
			paramMap.put("mch_id", PropertyUtil.getValue("swift_mer_id"));
			paramMap.put("out_trade_no", yintongPayRequestModel.getOrderId());
			paramMap.put("total_fee", new BigDecimal(yintongPayRequestModel.getAmount()).multiply(new BigDecimal(100)).longValue() + "");
			paramMap.put("mch_create_ip", IPMacUtils.getIpAddr(request));
			paramMap.put("notify_url", PropertyUtil.getValue("swiftpay_notify_url"));
			paramMap.put("nonce_str", TmDateUtil.nowTime(TmDateUtil.TIMESTAMP_FOMART_OTHER)  + RandomStringUtils.random(4, true, true));
			if (orderEffectiveTime > 0) {
				paramMap.put("time_start", DateFormatUtils.format(new Date(), DateUtils.DATE_TIME_FMT_OTHER));
				paramMap.put("time_expire",DateFormatUtils.format(TmDateUtil.addHours(new Date(),orderEffectiveTime), DateUtils.DATE_TIME_FMT_OTHER));
			}
			String preStr = HttpParamsUtils.buildPayParams(paramMap, false, true);
			logger.debug("威富通加密前:" + preStr);
			String sign = MD5.sign(preStr, "&key=" + PropertyUtil.getValue("swift_mer_key"), "utf-8");
			paramMap.put("sign", sign);
			String requestStr = XmlUtils.parseXML(paramMap);
			logger.debug("威富通请求参数:" + requestStr);
			HttpPost httpPost = new HttpPost(PropertyUtil.getValue("swiftpay_req_url"));
			StringEntity entityParams = new StringEntity(requestStr, "utf-8");
			httpPost.setEntity(entityParams);
			httpPost.setHeader("Content-Type", "text/xml;charset=ISO-8859-1");
			client = HttpClients.createDefault();
			response = client.execute(httpPost);
			if (response != null && response.getEntity() != null) {
				InputStream resStream = response.getEntity().getContent();
				logger.debug("威富通 支付请求返回参数：" + resStream.toString());
				Map<String, String> resultMap = XmlUtils.toMap(resStream, "utf-8");
				if (resultMap.containsKey("sign")) {
					if (SignUtils.checkParam(resultMap, PropertyUtil.getValue("swift_mer_key"))) {
						if ("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))) {
							Map orderResult = new HashMap();
							orderResult.put("codeUrl", resultMap.get("code_url"));
							orderResult.put("codeImgUrl", resultMap.get("code_img_url"));
							return CommonResponseUtils.successResponse(orderResult);
						}
					}
				}
				return CommonResponseUtils.failureResponse(resultMap.get("message"));
			} else {
				logger.debug("威富通服务器异常");
				return CommonResponseUtils.failureResponse(SUConstants.SERVER_ERROR);
			}
		} catch (Exception e) {
			logger.debug("威富通获取支付异常", e);
			return CommonResponseUtils.failureResponse(SUConstants.SERVER_ERROR);
		} finally {
			if (response != null) {
				response.close();
			}
			if (client != null) {
				client.close();
			}
		}
	}

	/**
	 * 收款通知处理
	 */
	@Override
	public Map payNotify(Map resultMap) {
		if (SignUtils.checkParam(resultMap, PropertyUtil.getValue("swift_mer_key"))) {
			logger.debug("订单验签通过");
			OrderPayCallBackModel orderPayCallBackModel = new OrderPayCallBackModel();
			transModel(resultMap, orderPayCallBackModel);
			incomHandleService.handleOrderCallBack(orderPayCallBackModel);
			return CommonResponseUtils.successResponse("success");
		} else {
			logger.debug("威富通订单通知 验证签名不通过");
		}
		return CommonResponseUtils.failureResponse((String) resultMap.get("message"));
	}


	private void transModel(Map map, OrderPayCallBackModel orderPayCallBackModel) {
		orderPayCallBackModel.setOrdId((String) map.get("out_trade_no"));
		orderPayCallBackModel.setPaymentAmt(new BigDecimal((String) map.get("total_fee")).divide(new BigDecimal(100)).doubleValue());
		orderPayCallBackModel.setPaymentId((String) map.get("transaction_id"));
		orderPayCallBackModel.setPaymentTime((String) map.get("time_end"));
		String result = (String) map.get("pay_result");
		orderPayCallBackModel.setTransStatus("0".equals(result) ? "S" : "F");
	}


}
